package com.openNetty.server.nettyclient;

import com.openNetty.common.bean.ComRequest;
import com.openNetty.common.bean.SendMsgFuture;
import com.openNetty.common.system.LoggerUtil;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.*;
import io.netty.handler.stream.ChunkedWriteHandler;

import static com.openNetty.common.utils.HttpMsgInit.setHttpMsg;

/**
 * Netty 客户端绑定类
 *
 * @author zhenggm
 * @create 2017-08-21 下午 4:29
 */
public class NettyClient {
    private static LoggerUtil logger = LoggerUtil.getLogger(NettyClient.class);

    /**
     * 绑定服务器，进行通信
     *
     * @param port    端口
     * @param ip      主机号
     * @param request 请求类
     * @return Future
     */
    public SendMsgFuture connect(int port, String ip, ComRequest request) {
        logger.debug("port :" + port + " ip:" + ip + " message:" + request.getMessage() + " method:" + request.getMethod());
        EventLoopGroup group = new NioEventLoopGroup();
        SendMsgFuture future = new SendMsgFuture();
        try {

            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(group)
                    .channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            // 客户端，对请求编码
                            ch.pipeline().addLast("http-encoder",
                                    new HttpRequestEncoder());
                            // 客户端，对响应解码
                            ch.pipeline().addLast("http-decoder",
                                    new HttpResponseDecoder());
                            // 聚合器，把多个消息转换为一个单一的FullHttpRequest或是FullHttpResponse
                            ch.pipeline().addLast("http-aggregator",
                                    new HttpObjectAggregator(1024 * 1024 * 1024));
                            // 块写入处理器
                            ch.pipeline().addLast("http-chunked",
                                    new ChunkedWriteHandler());
//                            ch.pipeline().addLast(new ReadTimeoutHandler(15));
//                            ch.pipeline().addLast(new WriteTimeoutHandler(10));
                            ch.pipeline().addLast(new SimpleClientHandler(future,request));
                        }
                    });

            //发起异步链接操作
            ChannelFuture channelFuture = bootstrap.connect(ip, port).sync();

            DefaultFullHttpRequest defaultRequest = setHttpMsg(request);
            channelFuture.channel().write(defaultRequest);
            channelFuture.channel().flush();
            //future.sync(20, TimeUnit.SECONDS);
            logger.debug("=================== START =============================");
            channelFuture.channel().closeFuture().sync();
            logger.debug("==================== END ==============================");
        } catch (Exception e) {
           logger.error(e);
        } finally {
            //关闭，释放线程资源
            group.shutdownGracefully();
        }
        return future;
    }


}
